package cc.autoapi.pucong.liteflow.design.utils;

import cc.autoapi.pucong.liteflow.design.core.exception.DesignException;
import cc.autoapi.pucong.liteflow.design.mobal.NodeCodeEnum;
import cc.autoapi.pucong.liteflow.design.mobal.el.ApiDesignNode;
import cc.autoapi.pucong.liteflow.design.mobal.el.ApiElChunkVo;
import cc.autoapi.pucong.liteflow.design.mobal.el.ApiNode;
import cc.autoapi.pucong.liteflow.design.mobal.el.ApiNodeRelation;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yomahub.liteflow.builder.el.*;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author pucong
 * @url https://gitee.com/pucong
 * @create 2023-05-31
 */
public class ElDesignUtils {

    public static void main(String[] args) {
        testJson();
//        testEl();
    }

    private static void testEl() {
        ELWrapper el = ELBus.forOpt(ELBus.node("a").data("test", "{a:1}")).doOpt("b");
//        ELWrapper el = ELBus.then(ELBus.node("a").data("test", "{a:1}"), "b", ELBus.when(ELBus.node("a").tag("123"), "d"));

        // 输出el表达式
        String el2 = el.toEL(true);
        System.out.println(el2);
//        String el1 = "IF(x, a, b)";
//        List<ApiNodeRelation> addRelateList = new ArrayList<>();
//        List<ApiDesignNode> addNodeList = new ArrayList<>();
//        System.out.println(el1);
//        el1 = el1.replaceAll(" ", "");
//        el1 = el1.replaceAll("\r", "");
//        el1 = el1.replaceAll("\n", "");
//        el1 = el1.replaceAll("\t", "");
//
//        dealEl2List(el1, addRelateList, addNodeList);
//        for (ApiDesignNode apiDesignNode : addNodeList) {
//            System.out.println(apiDesignNode.getId() + ":" + apiDesignNode.getName() + ":" + apiDesignNode.getParentId());
//        }
//        for (ApiNodeRelation apiNodeRelation : addRelateList) {
//            System.out.println(JSONObject.toJSONString(apiNodeRelation));
//        }
    }

    private static void testJson() {
//        String json = "{\"cells\":[{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"7b5f24c7-f8b1-4f8f-9af5-34506e56bd90\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"port\":\"right\"},\"target\":{\"cell\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"707cc37b-f675-4203-8bd7-c363bb96536d\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"port\":\"right\"},\"target\":{\"cell\":\"129d1b54-756f-4fa7-b3bd-0196bc9a46a7\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"64138e11-0f42-4c9b-98f5-ec5449affb76\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"129d1b54-756f-4fa7-b3bd-0196bc9a46a7\",\"port\":\"right\"},\"target\":{\"cell\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"8b9bfd06-bf53-4ed5-b343-e3cbc98b8cbc\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"port\":\"right\"},\"target\":{\"cell\":\"5eb7346e-c499-40e8-aea4-33d3f99b1055\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"7940c816-6b66-40b7-a528-3b9dc1f1b2cb\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"5eb7346e-c499-40e8-aea4-33d3f99b1055\",\"port\":\"right\"},\"target\":{\"cell\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"8f12d41d-0504-4ea6-8a7a-3c7a078de47e\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"port\":\"right\"},\"target\":{\"cell\":\"e7e00bcc-e5ff-469a-ac0f-eaf08eb3f154\",\"port\":\"left\"}},{\"position\":{\"x\":460,\"y\":240},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"a\",\"execNodeCode\":null},\"zIndex\":1},{\"position\":{\"x\":980,\"y\":20},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"b\",\"execNodeCode\":null},\"zIndex\":2},{\"position\":{\"x\":980,\"y\":520},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"129d1b54-756f-4fa7-b3bd-0196bc9a46a7\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"b\",\"execNodeCode\":null},\"zIndex\":3},{\"position\":{\"x\":2080,\"y\":320},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"c\",\"execNodeCode\":null},\"zIndex\":4},{\"position\":{\"x\":1503,\"y\":-51},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"5eb7346e-c499-40e8-aea4-33d3f99b1055\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"ae8b7c8ff9724ec48a48d7598e5d8c3b\",\"execNodeCode\":null},\"zIndex\":5},{\"position\":{\"x\":2560,\"y\":340},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"e7e00bcc-e5ff-469a-ac0f-eaf08eb3f154\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"a\",\"execNodeCode\":null},\"zIndex\":6}]}";
//        String json = "{\"cells\":[{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"7b5f24c7-f8b1-4f8f-9af5-34506e56bd90\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"port\":\"right\"},\"target\":{\"cell\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"707cc37b-f675-4203-8bd7-c363bb96536d\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"port\":\"right\"},\"target\":{\"cell\":\"129d1b54-756f-4fa7-b3bd-0196bc9a46a7\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"64138e11-0f42-4c9b-98f5-ec5449affb76\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"129d1b54-756f-4fa7-b3bd-0196bc9a46a7\",\"port\":\"right\"},\"target\":{\"cell\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"cd43ad39-992b-4914-82f4-ef0886a937ae\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"port\":\"right\"},\"target\":{\"cell\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"port\":\"left\"}},{\"position\":{\"x\":460,\"y\":240},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"a\",\"execNodeCode\":null},\"zIndex\":1},{\"position\":{\"x\":980,\"y\":20},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"b\",\"execNodeCode\":null},\"zIndex\":2},{\"position\":{\"x\":1000,\"y\":560},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"129d1b54-756f-4fa7-b3bd-0196bc9a46a7\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"b\",\"execNodeCode\":null},\"zIndex\":3},{\"position\":{\"x\":1620,\"y\":280},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"c\",\"execNodeCode\":null},\"zIndex\":4}]}";
        String json = "{\"cells\":[{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"7b5f24c7-f8b1-4f8f-9af5-34506e56bd90\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"port\":\"right\"},\"target\":{\"cell\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"cd43ad39-992b-4914-82f4-ef0886a937ae\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"port\":\"right\"},\"target\":{\"cell\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"port\":\"left\"}},{\"position\":{\"x\":460,\"y\":240},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"37528a80-0bb9-43a5-bfdb-3e2c4b75b692\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"a\",\"execNodeCode\":null},\"zIndex\":1},{\"position\":{\"x\":1060,\"y\":180},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"2b506016-ac13-4b6f-9086-40201e21f641\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"b\",\"execNodeCode\":null},\"zIndex\":2},{\"position\":{\"x\":1620,\"y\":280},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"a07a0982-e315-42b7-af2c-161b47668e50\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"c\",\"execNodeCode\":null},\"zIndex\":4}]}";
//        String json = "{\"cells\":[{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"6939a897-2437-457e-98cd-321562c957d5\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"0918803b-990b-4a88-96c6-c16acacd71d8\",\"port\":\"right\"},\"target\":{\"cell\":\"5d70a33f-3bb7-4e01-b8b4-1fdbe99d0f0c\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"bcb5a98a-dba0-4ea4-8b68-e544cc84ea90\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"5d70a33f-3bb7-4e01-b8b4-1fdbe99d0f0c\",\"port\":\"right\"},\"target\":{\"cell\":\"39f4c0c4-0c09-4de0-b7a9-411d154e1505\",\"port\":\"left\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\",\"targetMarker\":{\"name\":\"block\",\"width\":12,\"height\":8},\"strokeDasharray\":2,\"style\":{\"animation\":\"ant-line 30s infinite linear\"}}},\"id\":\"4dddf8d7-00cb-45f7-a03b-9a0aac66e393\",\"inherit\":\"edge\",\"zIndex\":0,\"source\":{\"cell\":\"0918803b-990b-4a88-96c6-c16acacd71d8\",\"port\":\"right\"},\"target\":{\"cell\":\"4d05b839-a5c4-49fa-817d-a1d317110351\",\"port\":\"left\"}},{\"position\":{\"x\":400,\"y\":-200},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"0918803b-990b-4a88-96c6-c16acacd71d8\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"a\",\"execNodeCode\":null,\"data\":\"name\"},\"zIndex\":2},{\"position\":{\"x\":1000,\"y\":-240},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"5d70a33f-3bb7-4e01-b8b4-1fdbe99d0f0c\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"b\",\"execNodeCode\":null},\"zIndex\":3},{\"position\":{\"x\":1480,\"y\":-311},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"39f4c0c4-0c09-4de0-b7a9-411d154e1505\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"c\",\"execNodeCode\":null},\"zIndex\":4},{\"position\":{\"x\":1000,\"y\":188},\"size\":{\"width\":360,\"height\":342},\"view\":\"vue-shape-view\",\"shape\":\"custom-vue-node\",\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"id\":\"top\",\"group\":\"top\"},{\"id\":\"right\",\"group\":\"right\"},{\"id\":\"bottom\",\"group\":\"bottom\"},{\"id\":\"left\",\"group\":\"left\"}]},\"id\":\"4d05b839-a5c4-49fa-817d-a1d317110351\",\"data\":{\"id\":\"common\",\"nodeCode\":\"common\",\"name\":\"一般组件\",\"scriptType\":\"js\",\"label\":\"一般组件\",\"desc\":\"一般组件\",\"execNodeId\":\"c\",\"execNodeCode\":null},\"zIndex\":5}]}";
        List<ApiNodeRelation> addRelateList = new ArrayList<>();
        List<ApiNode> addNodeList = new ArrayList<>();
        ElDesignUtils.dealJson2List(json, addNodeList, addRelateList);
        String el = ElDesignUtils.getEl(addNodeList, addRelateList);
        System.out.println(el);
    }

    public static void dealEl2List(String el, List<ApiNodeRelation> addRelateList, List<ApiDesignNode> addNodeList) {
        el = el.toLowerCase();
        String[] split = el.split(";");
        // 记录子变量信息
        Map<String, ApiElChunkVo> chunkMap = new HashMap<>();
        for (String el2 : split) {
            // 去掉空格和换行
            el2 = el2.replaceAll(" ", "");
            el2 = el2.replaceAll("\r", "");
            el2 = el2.replaceAll("\n", "");
            el2 = el2.replaceAll("\t", "");

            // 是定义变量
            if (el2.contains("='")) {
                continue;
            }
            // 是子变量
            if (el2.contains("=")) {
                int i = el2.indexOf("=");
                String key = el2.substring(0, i);
                String value = el2.substring(i, el2.length());
                ApiElChunkVo chunkVo = dealEl2List2(value, "", null, chunkMap);
                chunkMap.put(key, chunkVo);
                continue;
            }
            // 是普通流程
            ApiElChunkVo apiElChunkVo = dealEl2List2(el2, "", null, chunkMap);
            addRelateList.addAll(apiElChunkVo.getRelateList());
            addNodeList.addAll(apiElChunkVo.getNodeList());
        }
    }

    private static ApiElChunkVo dealEl2List2(String el, String parentId, List<String> beforeIds, Map<String, ApiElChunkVo> chunkMap) {
        if (el.startsWith("then(") || el.startsWith("ser(")) {
            String str = getElChunkByTime(el, 1);
            // 进行分块
            List<String> splits = getElChunk(str);
            return dealEl2ListThen(splits, parentId, beforeIds, chunkMap);
        } else if (el.startsWith("when(") || el.startsWith("par(")) {
            String str = getElChunkByTime(el, 1);
            // 进行分块
            List<String> splits = getElChunk(str);
            return dealEl2ListPar(splits, parentId, beforeIds, chunkMap);
        } else if (el.startsWith("switch(")) {
            String str = getElChunkByTime(el, 1);
            ApiElChunkVo chunkVo = dealEl2List2(str, parentId, beforeIds, chunkMap);
            List<String> rootIds = chunkVo.getRootIds();
            List<ApiDesignNode> nodes = chunkVo.getNodeList();
            ApiDesignNode switchNode = nodes.get(0);
            switchNode.setNodeType(NodeCodeEnum.SWITCH);
            switchNode.setExecNodeName(switchNode.getName());

            List<ApiNodeRelation> relateList = chunkVo.getRelateList();
            String str2 = getElChunkByTime(el, 2);
            // 进行分块
            List<String> splits = getElChunk(str2);
            ApiElChunkVo chunkVo1 = dealEl2ListPar(splits, parentId, Arrays.asList(switchNode.getId()), chunkMap);
            chunkVo1.getNodeList().add(switchNode);
            chunkVo1.getRelateList().addAll(relateList);
            chunkVo1.setRootIds(rootIds);
            return chunkVo1;
        } else if (el.startsWith("catch(")) {
            /**
             *  CATCH(
             *    THEN(a,b)
             *  ).DO(c)
             */
            ApiDesignNode catchNode = new ApiDesignNode();
            catchNode.setId(UUID.randomUUID().toString());
            catchNode.setNodeType(NodeCodeEnum.CATCH);
            catchNode.setName(NodeCodeEnum.CATCH.getName());
            catchNode.setParentId(parentId);

            String str = getElChunkByTime(el, 1);
            ApiElChunkVo chunkVo = dealEl2List2(str, catchNode.getId(), Arrays.asList(catchNode.getId()), chunkMap);

            String str2 = getElChunkByTime(el, 2);
            if (StringUtils.isNotBlank(str2)) {
                ApiDesignNode catchDoNode = new ApiDesignNode();
                catchDoNode.setId(UUID.randomUUID().toString());
                catchDoNode.setNodeType(NodeCodeEnum.CATCH_END);
                catchDoNode.setName(NodeCodeEnum.CATCH_END.getName());
                catchDoNode.setParentId(parentId);

                ApiElChunkVo chunkVo2 = dealEl2List2(str2, parentId, Arrays.asList(catchNode.getId()), chunkMap);
                ApiDesignNode apiDesignNode = chunkVo2.getNodeList().get(0);
                catchDoNode.setExecNodeName(apiDesignNode.getName());

                chunkVo.getNodeList().add(catchDoNode);

                ApiNodeRelation relation = new ApiNodeRelation();
                relation.setId(UUID.randomUUID().toString());
                relation.setSourceNodeId(catchNode.getId());
                relation.setTargetNodeId(catchDoNode.getId());
                chunkVo.getRelateList().add(relation);
            }

            chunkVo.getNodeList().add(catchNode);
            chunkVo.setRootIds(Arrays.asList(catchNode.getId()));
            return chunkVo;
        } else if (el.startsWith("if(")) {
            // IF(x, a, b)
            // IF(x, a).ELSE(b);
            // IF(x1, a).ELIF(x2, b).ELIF(x3, c).ELIF(x4, d).ELSE(THEN(m, n));
            String str = getElChunkByTime(el, 1);
            // 进行分块
            List<String> splits = getElChunk(str);
            ApiElChunkVo chunkVo = dealEl2ListIf(splits, parentId, beforeIds, chunkMap);
            List<String> endIds = chunkVo.getEndIds();

            List<String> elifs = getElChunksByWord(el, ".elif");
            for (String elif : elifs) {
                String elChunkByTime = getElChunkByTime(elif, 1);
                List<String> splits2 = getElChunk(elChunkByTime);
                ApiElChunkVo chunkVo2 = dealEl2ListIf(splits2, parentId, endIds, chunkMap);

                chunkVo.getNodeList().addAll(chunkVo2.getNodeList());
                chunkVo.getRelateList().addAll(chunkVo2.getRelateList());
                chunkVo.setEndIds(chunkVo2.getEndIds());

                endIds = chunkVo2.getEndIds();
            }

            List<String> elses = getElChunksByWord(el, ".else");
            if (elses.size() == 1) {
                String else1 = elses.get(0);
                String elChunkByTime = getElChunkByTime(else1, 1);
                ApiElChunkVo chunkVo2 = dealEl2List2(elChunkByTime, parentId, endIds, chunkMap);

                chunkVo.getNodeList().addAll(chunkVo2.getNodeList());
                chunkVo.getRelateList().addAll(chunkVo2.getRelateList());
                chunkVo.setEndIds(chunkVo2.getEndIds());
            }
            return chunkVo;
        } else if (el.startsWith("for(") || el.startsWith("while(") || el.startsWith("iterator(")) {
            String str = getElChunkByTime(el, 1);
            ApiElChunkVo chunkVo = dealEl2List2(str, parentId, beforeIds, chunkMap);

            List<ApiDesignNode> nodeList = chunkVo.getNodeList();
            ApiDesignNode forNode = nodeList.get(0);
            if (el.startsWith("for(")) {
                forNode.setNodeType(NodeCodeEnum.FOR);
            } else if (el.startsWith("while(")) {
                forNode.setNodeType(NodeCodeEnum.WHILE);
            } else if (el.startsWith("iterator(")) {
                forNode.setNodeType(NodeCodeEnum.ITERATOR);
            }
            forNode.setExecNodeName(forNode.getName());
            // 进行分块
            List<String> elChunksByWord = getElChunksByWord(el, ".do");
            String elChunkByTime = getElChunkByTime(elChunksByWord.get(0), 1);
            ApiElChunkVo chunkVo2 = dealEl2List2(elChunkByTime, forNode.getId(), null, chunkMap);

            nodeList.addAll(chunkVo2.getNodeList());
            chunkVo.getRelateList().addAll(chunkVo2.getRelateList());
            chunkVo.setEndIds(chunkVo2.getEndIds());

            List<String> elChunksByWord3 = getElChunksByWord(el, ".break");
            if (elChunksByWord3.size() > 0) {
                String elChunkByTime3 = getElChunkByTime(elChunksByWord3.get(0), 1);
                ApiElChunkVo chunkVo3 = dealEl2List2(elChunkByTime3, parentId, chunkVo.getEndIds(), chunkMap);

                nodeList.addAll(chunkVo3.getNodeList());
                chunkVo.getRelateList().addAll(chunkVo3.getRelateList());
                chunkVo.setEndIds(chunkVo3.getEndIds());
            }
            return chunkVo;
        } else if (el.startsWith("node(")) {
            List<String> node = getElChunksByWord(el, "node");
            String node0 = getElChunkByTime(node.get(0), 1);
            ApiElChunkVo chunkVo = dealEl2List2(node0, parentId, beforeIds, chunkMap);
            List<ApiDesignNode> nodeList = chunkVo.getNodeList();
            ApiDesignNode node1 = nodeList.get(0);
            // 读取data
            List<String> elChunksByWord2 = getElChunksByWord(el, ".data");
            if (elChunksByWord2.size() > 0) {
                String data = getElChunkByTime(elChunksByWord2.get(0), 1);
                node1.setData(data);
            }
            // 读取tag
            List<String> elChunksByWord3 = getElChunksByWord(el, ".tag");
            if (elChunksByWord3.size() > 0) {
                String tag = getElChunkByTime(elChunksByWord3.get(0), 1);
                node1.setData(tag);
            }
            return chunkVo;
        } else {
            List<ApiNodeRelation> addRelateList = new ArrayList<>();
            List<ApiDesignNode> addNodeList = new ArrayList<>();
            // 是节点或者子流程或者子变量
            ApiElChunkVo chunkVo = chunkMap.get(el);
            if (chunkVo != null) {
                return chunkVo;
            }
            ApiDesignNode node = new ApiDesignNode();
            node.setId(UUID.randomUUID().toString());
            node.setName(el.replaceAll("\"", ""));
            node.setNodeType(NodeCodeEnum.common);
            node.setParentId(parentId);
            addNodeList.add(node);

            if (beforeIds != null) {
                for (String beforeId : beforeIds) {
                    ApiNodeRelation relation = new ApiNodeRelation();
                    relation.setId(beforeId + "_" + node.getId());
                    relation.setSourceNodeId(beforeId);
                    relation.setTargetNodeId(node.getId());
                    addRelateList.add(relation);
                }
            }
            ApiElChunkVo chunkVo2 = new ApiElChunkVo();
            chunkVo2.setNodeList(addNodeList);
            chunkVo2.setRelateList(addRelateList);
            chunkVo2.setRootIds(Arrays.asList(node.getId()));
            chunkVo2.setEndIds(Arrays.asList(node.getId()));
            return chunkVo2;
        }
    }

    /**
     * 判断一个字符串是否是数字。
     *
     * @param string
     * @return
     */
    private static boolean isNumber(String string) {
        if (string == null)
            return false;
        Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
        return pattern.matcher(string).matches();
    }

    private static ApiElChunkVo dealEl2ListIf(List<String> splits, String parentId, List<String> beforeIds, Map<String, ApiElChunkVo> chunkMap) {
        List<String> endIds = null;

        String first = splits.get(0);
        ApiElChunkVo chunkVo = dealEl2List2(first, parentId, beforeIds, chunkMap);
        List<ApiDesignNode> nodes = chunkVo.getNodeList();
        ApiDesignNode ifNode = nodes.get(0);
        ifNode.setNodeType(NodeCodeEnum.IF);
        ifNode.setExecNodeName(ifNode.getName());
        List<String> rootIds1 = chunkVo.getRootIds();

        String second = splits.get(1);
        ApiElChunkVo chunkVo2 = dealEl2List2(second, parentId, rootIds1, chunkMap);
        List<ApiDesignNode> addNodeList2 = chunkVo2.getNodeList();
        List<ApiNodeRelation> addRelateList2 = chunkVo2.getRelateList();
        chunkVo.getNodeList().addAll(addNodeList2);
        chunkVo.getRelateList().addAll(addRelateList2);
        endIds = chunkVo2.getEndIds();

        if (splits.size() > 2) {
            String thread = splits.get(2);
            ApiElChunkVo chunkVo3 = dealEl2List2(thread, parentId, rootIds1, chunkMap);
            List<ApiDesignNode> addNodeList3 = chunkVo3.getNodeList();
            List<ApiNodeRelation> addRelateList3 = chunkVo3.getRelateList();

            chunkVo.getNodeList().addAll(addNodeList3);
            chunkVo.getRelateList().addAll(addRelateList3);
            endIds = chunkVo3.getEndIds();
        }
        chunkVo.setEndIds(endIds);
        return chunkVo;
    }

    private static ApiElChunkVo dealEl2ListPar(List<String> splits, String parentId, List<String> beforeIds, Map<String, ApiElChunkVo> chunkMap) {
        List<ApiNodeRelation> addRelateList = new ArrayList<>();
        List<ApiDesignNode> addNodeList = new ArrayList<>();

        List<String> rootIdsPre = new ArrayList<>();
        for (String split : splits) {
            ApiElChunkVo chunkVo = dealEl2List2(split, parentId, beforeIds, chunkMap);
            List<ApiDesignNode> addNodeList1 = chunkVo.getNodeList();
            List<ApiNodeRelation> addRelateList1 = chunkVo.getRelateList();
            List<String> rootIds = chunkVo.getRootIds();
            List<String> endIds = chunkVo.getEndIds();

            addRelateList.addAll(addRelateList1);
            addNodeList.addAll(addNodeList1);

            rootIdsPre.addAll(rootIds);
        }
        // 获取开始和结束节点
        ApiElChunkVo chunkVo2 = new ApiElChunkVo();
        chunkVo2.setNodeList(addNodeList);
        chunkVo2.setRelateList(addRelateList);
        chunkVo2.setRootIds(rootIdsPre);
        return chunkVo2;
    }

    private static ApiElChunkVo dealEl2ListThen(List<String> splits, String parentId, List<String> beforeIds, Map<String, ApiElChunkVo> chunkMap) {
        List<ApiNodeRelation> addRelateList = new ArrayList<>();
        List<ApiDesignNode> addNodeList = new ArrayList<>();

        List<String> rootIdsPre = null;
        List<String> endIdsPre = beforeIds;
        for (String split : splits) {
            ApiElChunkVo chunkVo = dealEl2List2(split, parentId, endIdsPre, chunkMap);
            List<ApiDesignNode> addNodeList1 = chunkVo.getNodeList();
            List<ApiNodeRelation> addRelateList1 = chunkVo.getRelateList();
            List<String> rootIds = chunkVo.getRootIds();
            List<String> endIds = chunkVo.getEndIds();

            addRelateList.addAll(addRelateList1);
            addNodeList.addAll(addNodeList1);
            if (rootIdsPre == null) {
                rootIdsPre = rootIds;
            }
            if (endIds == null || endIds.size() == 0) {
                endIdsPre = rootIds;
            } else {
                endIdsPre = endIds;
            }
        }
        // 获取开始和结束节点
        ApiElChunkVo chunkVo2 = new ApiElChunkVo();
        chunkVo2.setNodeList(addNodeList);
        chunkVo2.setRelateList(addRelateList);
        chunkVo2.setRootIds(rootIdsPre);
        chunkVo2.setEndIds(endIdsPre);
        return chunkVo2;
    }

    /**
     * 按照逗号进行分块
     * A,SWITCH(B).to(THEN(D, E, F).id("t1"),THEN(C,WHEN(THEN(SWITCH(G).to(THEN(H, I).id("t2"), J),K),THEN(L, M))).id("t3")),Z
     *
     * @param str
     * @return
     */
    private static List<String> getElChunk(String str) {
        List<String> list = new ArrayList<>();
        char[] charArray = str.toCharArray();
        StringBuffer sbf = new StringBuffer();
        int step = 0;
        for (int i = 0; i < charArray.length; i++) {
            char c = charArray[i];
            if (c == '(') {
                step++;
            } else if (c == ')') {
                step--;
            }
            if (!(c == ',' && step == 0)) {
                sbf.append(c);
            }
            if ((c == ',' && step == 0) || i == charArray.length - 1) {
                list.add(sbf.toString());
                sbf = new StringBuffer();
            }
        }
        return list;
    }


    /**
     * 获取关键词开头的内容
     *
     * @param str
     * @param word
     * @return
     */
    private static List<String> getElChunksByWord(String str, String word) {
        List<String> strings = new ArrayList<>();

        char[] charArray = str.toCharArray();
        StringBuffer sbf = new StringBuffer();
        int step = 0;
        for (char c : charArray) {
            if (c == '(') {
                step++;
            } else if (c == ')') {
                step--;
            }
            sbf.append(c);
            if (c == ')' && step == 0) {
                String string = sbf.toString();
                if (string.startsWith(word)) {
                    strings.add(string);
                }
                sbf = new StringBuffer();
            }
        }
        return strings;
    }


    /**
     * 获取第 {time} 次括号内的内容
     *
     * @param str
     * @param time
     * @return
     */
    private static String getElChunkByTime(String str, Integer time) {
        char[] charArray = str.toCharArray();
        StringBuffer sbf = new StringBuffer();
        int time2 = 0;
        int step = 0;
        boolean start = false;
        for (char c : charArray) {
            boolean first = false;
            if (c == '(') {
                if (step == 0) {
                    first = true;
                }
                step++;
                start = true;
            } else if (c == ')') {
                step--;
            }
            if (start) {
                if (step == 0) {
                    if (c != '(' && c != ')') {
                        sbf.append(c);
                    }
                } else if (!first) {
                    sbf.append(c);
                }
            }
            if (c == ')' && step == 0) {
                time2++;
                if (time2 == time) {
                    break;
                }
                sbf = new StringBuffer();
                start = false;
            }
        }
        return sbf.toString();
    }

    public static void dealJson2List(String jsonStr, List<ApiNode> addNodeList, List<ApiNodeRelation> addRelateList) {
        if (StringUtils.isBlank(jsonStr)) {
            return;
        }
        JSONObject json = JSONObject.parseObject(jsonStr);
        JSONArray cells = json.getJSONArray("cells");
        if (cells == null) {
            return;
        }
        for (Object cell : cells) {
            JSONObject cellJson = (JSONObject) cell;
            String shape = cellJson.getString("shape");
            String id = cellJson.getString("id");
            if (shape.equals("edge")) {
                JSONObject source = cellJson.getJSONObject("source");
                String sourceCellId = source.getString("cell");

                JSONObject target = cellJson.getJSONObject("target");
                String targetCellId = target.getString("cell");
                if (StringUtils.isBlank(targetCellId)) {
                    continue;
                }
                if (StringUtils.isBlank(sourceCellId)) {
                    continue;
                }
                ApiNodeRelation nodeRelation = new ApiNodeRelation();
                nodeRelation.setId(id);
                nodeRelation.setSourceNodeId(sourceCellId);
                nodeRelation.setTargetNodeId(targetCellId);
                addRelateList.add(nodeRelation);
            } else if (shape.equals("custom-vue-node") || shape.equals("custom-group-node") || shape.equals("custom-check-node")) {
                JSONObject data = cellJson.getJSONObject("data");
                String parentId = cellJson.getString("parent");
                String data2 = data.getString("data");
                String execNodeId = data.getString("execNodeId");
                String scriptData = data.getString("scriptData");
                String scriptLanguage = data.getString("scriptLanguage");
                String nodeCode = data.getString("nodeCode");
                String tag = data.getString("tag");
                String name = data.getString("name");
                ApiNode apiNode = new ApiNode();
                apiNode.setId(id);
                apiNode.setParentId(parentId);
                apiNode.setExecNodeId(execNodeId);
                apiNode.setName(name);
                apiNode.setScriptLanguage(scriptLanguage);
                apiNode.setScriptData(scriptData);
                apiNode.setType(NodeCodeEnum.valueOf(nodeCode));
                apiNode.setCmpData(data2);
                apiNode.setTag(tag);
                addNodeList.add(apiNode);
            }
        }
    }

    public static String getEl(List<ApiNode> projectApiNodeList, List<ApiNodeRelation> projectApiNodeRelationList) {
        Map<String, ApiNode> nodeInfoMap = projectApiNodeList.stream().collect(Collectors.toMap(ApiNode::getId, Function.identity(), (key1, key2) -> key2));
        // 获取开始节点
        List<ApiNode> rootNodes = getRootNode(projectApiNodeRelationList, projectApiNodeList, nodeInfoMap);
        String endNodeId = null;
        if (rootNodes.size() > 1) {
            ApiNode endNode = getEndNode(rootNodes, nodeInfoMap, projectApiNodeRelationList);
            endNodeId = endNode.getId();
            ELWrapper el = getEl(rootNodes, endNodeId, nodeInfoMap, projectApiNodeRelationList);
            ELWrapper el2 = getEl(endNode, null, nodeInfoMap, projectApiNodeRelationList);
            ThenELWrapper then = ELBus.then(el, el2);
            return then.toEL(true);
        } else if (rootNodes.size() == 1) {
            ELWrapper el = getEl(rootNodes.get(0), null, nodeInfoMap, projectApiNodeRelationList);
            if (el instanceof NodeELWrapper) {
                ThenELWrapper then = ELBus.then(el);
                return then.toEL(true);
            }
            return el.toEL(true);
        } else {
            throw new DesignException("不存在根节点");
        }
    }


    private static ELWrapper getEl(ApiNode rootNode, String endNodeId, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> apiNodeRelations) {
        ThenELWrapper then = null;
        ApiNode currentNode = rootNode;
        Boolean isEnd = false;
        for (int i2 = 0; !isEnd; i2++) {
            if (currentNode == null) {
                isEnd = true;
                continue;
            }
            List<ApiNode> nextNodes = getNextNode(currentNode, nodeInfoMap, apiNodeRelations);
            if (endNodeId != null && nextNodes.size() == 1 && endNodeId.equals(nextNodes.get(0).getId())) {
                isEnd = true;
            }
            if (nextNodes.size() == 0) {
                isEnd = true;
            }
            ApiNode endNode = getEndNode(nextNodes, nodeInfoMap, apiNodeRelations);
            NodeCodeEnum nodeCode = currentNode.getType();
            if (NodeCodeEnum.SWITCH == nodeCode) {
                // SWITCH(a).to(b, c, d)
                SwitchELWrapper switchELWrapper = ELBus.switchOpt(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData()));
                List<ELWrapper> els = getEls(nextNodes, endNode, nodeInfoMap, apiNodeRelations);
                for (ELWrapper el : els) {
                    switchELWrapper.to(el);
                }
                if (then == null) {
                    then = ELBus.then(switchELWrapper);
                } else {
                    then.then(switchELWrapper);
                }
                isEnd = true;
            } else if (NodeCodeEnum.IF == nodeCode) {
                // IF(x, a, b)
                List<ELWrapper> els = getEls(nextNodes, endNode, nodeInfoMap, apiNodeRelations);
                IfELWrapper ifELWrapper = ELBus.ifOpt(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData()), els.get(0), els.get(1));
                if (then == null) {
                    then = ELBus.then(ifELWrapper);
                } else {
                    then.then(ifELWrapper);
                }
                isEnd = true;
            } else if (NodeCodeEnum.FOR == nodeCode) {
                // FOR(f).DO(THEN(a, b));
                ELWrapper el = getChildrenEls(currentNode.getId(), nodeInfoMap, apiNodeRelations);
                LoopELWrapper forELWrapper = ELBus.forOpt(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData())).doOpt(el);
                NodeELWrapper breakNode = getChildrenBreakNode(currentNode.getId(), nodeInfoMap);
                if (breakNode != null) {
                    forELWrapper.breakOpt(breakNode);
                }
                if (then == null) {
                    then = ELBus.then(forELWrapper);
                } else {
                    then.then(forELWrapper);
                }
            } else if (NodeCodeEnum.ITERATOR == nodeCode) {
                // ITERATOR(x).DO(THEN(a, b));
                ELWrapper el = getChildrenEls(currentNode.getId(), nodeInfoMap, apiNodeRelations);
                LoopELWrapper iteratorELWrapper = ELBus.iteratorOpt(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData())).doOpt(el);
                if (then == null) {
                    then = ELBus.then(iteratorELWrapper);
                } else {
                    then.then(iteratorELWrapper);
                }
            } else if (NodeCodeEnum.CATCH == nodeCode) {
                ELWrapper el = getChildrenEls(currentNode.getId(), nodeInfoMap, apiNodeRelations);
                ELWrapper catchEndNodeNameEls = getCatchEndNodeNameEls(currentNode.getId(), nodeInfoMap, apiNodeRelations);
                CatchELWrapper catchELWrapper = ELBus.catchException(el).doOpt(catchEndNodeNameEls);
                if (then == null) {
                    then = ELBus.then(catchELWrapper);
                } else {
                    then.then(catchELWrapper);
                }
            }
            if (NodeCodeEnum.FOR_SCRIPT == nodeCode || NodeCodeEnum.SCRIPT == nodeCode
                    || NodeCodeEnum.SWITCH_SCRIPT == nodeCode || NodeCodeEnum.BOOLEAN_SCRIPT == nodeCode
                    || NodeCodeEnum.common == nodeCode) {
                if (nextNodes.size() > 1) {
                    if (then == null) {
                        then = ELBus.then(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData()));
                    } else {
                        then.then(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData()));
                    }
                    List<ELWrapper> els = getEls(nextNodes, endNode, nodeInfoMap, apiNodeRelations);
                    WhenELWrapper when = ELBus.when();
                    for (ELWrapper el : els) {
                        when.when(el);
                    }
                    then.then(when);
                    // 再次获取后续节点
                    if (endNode != null) {
                        currentNode = endNode;
                    } else {
                        currentNode = null;
                    }
                } else {
                    if (then == null) {
                        then = ELBus.then(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData()));
                    } else {
                        then.then(getNodeName(currentNode.getExecNodeId(), currentNode.getTag(), currentNode.getCmpData()));
                    }
                    if (nextNodes.size() == 1) {
                        currentNode = nextNodes.get(0);
                    }
                }
            } else {
                currentNode = endNode;
            }
        }
        // 反射获取子节点数量
        List<ELWrapper> elWrapperList = getElWrapperListByReflect(then);
        if (elWrapperList.size() == 1) {
            return elWrapperList.get(0);
        }
        return then;
    }

    private static List<ELWrapper> getElWrapperListByReflect(ThenELWrapper then) {
        List<ELWrapper> elWrapperList = null;
        try {
            // 获取类的Class对象
            Class<?> clazz = then.getClass();
            // 获取父类的Class对象
            Class<?> parentClass = clazz.getSuperclass();
            // 获取属性对象
            Field field = parentClass.getDeclaredField("elWrapperList");
            // 设置属性可访问
            field.setAccessible(true);
            // 获取属性值
            elWrapperList = (List<ELWrapper>) field.get(then);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new DesignException("获取反射值失败");
        }
        return elWrapperList;
    }

    private static NodeELWrapper getChildrenBreakNode(String uuid, Map<String, ApiNode> nodeInfoMap) {
        // 获取子节点
        Set<String> strings = nodeInfoMap.keySet();
        for (String key : strings) {
            ApiNode apiNode = nodeInfoMap.get(key);
            if (StringUtils.isNotBlank(apiNode.getParentId()) && apiNode.getParentId().equals(uuid)) {
                if (apiNode.getType() == NodeCodeEnum.BREAK) {
                    return getNodeName(apiNode.getName(), apiNode.getTag(), apiNode.getCmpData());
                }
            }
        }
        return null;
    }

    private static ELWrapper getCatchEndNodeNameEls(String uuid, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> projectApiNodeRelationList) {
        // 获取子节点
        ApiNode catchEnd = null;
        for (ApiNodeRelation ApiNodeRelation : projectApiNodeRelationList) {
            if (ApiNodeRelation.getSourceNodeId().equals(uuid)) {
                ApiNode ApiNode1 = nodeInfoMap.get(ApiNodeRelation.getTargetNodeId());
                if (ApiNode1 != null && ApiNode1.getType() == NodeCodeEnum.CATCH_END) {
                    if (ApiNode1.getType() == NodeCodeEnum.CATCH_END) {
                        catchEnd = ApiNode1;
                        break;
                    }
                }
            }
        }
        if (catchEnd == null) {
            return null;
        }
        ELWrapper el = getChildrenEls(catchEnd.getId(), nodeInfoMap, projectApiNodeRelationList);
        return el;
    }

    private static NodeELWrapper getNodeName(String execNodeId, String tag, String cmdData) {
        NodeELWrapper data = ELBus.node(execNodeId);
        if (StringUtils.isNotBlank(tag)) {
            data.tag(tag);
        }
        if (StringUtils.isNotBlank(cmdData)) {
            data.data(getSerializName(), cmdData);
        }
        return data;
    }

    private static String getSerializName() {
        String s = "abcdefghijklmnopqrstuvwxyz";
        char[] c = s.toCharArray();
        StringBuffer stringBuffer = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < 8; i++) {
            stringBuffer.append(c[random.nextInt(c.length)]);
        }
        return stringBuffer.toString();
    }

    private static ELWrapper getChildrenEls(String uuid, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> projectApiNodeRelationList) {
        // 获取子节点
        List<ApiNode> projectApiNodeList = new ArrayList<>();
        Set<String> strings = nodeInfoMap.keySet();
        for (String key : strings) {
            ApiNode ApiNode = nodeInfoMap.get(key);
            if (StringUtils.isNotBlank(ApiNode.getParentId()) && ApiNode.getParentId().equals(uuid)) {
                projectApiNodeList.add(ApiNode);
            }
        }
        Map<String, ApiNode> nodeInfoMap2 = projectApiNodeList.stream().collect(Collectors.toMap(ApiNode::getId, Function.identity(), (key1, key2) -> key2));
        List<ApiNode> rootNodes = getChildrenRootNode(projectApiNodeRelationList, projectApiNodeList, nodeInfoMap2);
        String endNodeId = null;
        if (rootNodes.size() > 1) {
            ApiNode endNode = getEndNode(rootNodes, nodeInfoMap, projectApiNodeRelationList);
            endNodeId = endNode.getId();
        }
        ELWrapper el = getEl(rootNodes, endNodeId, nodeInfoMap2, projectApiNodeRelationList);
        return el;
    }


    private static ELWrapper getEl(List<ApiNode> rootNodes, String endNodeId, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> ApiNodeRelations) {
        if (rootNodes.size() == 1) {
            ELWrapper el = getEl(rootNodes.get(0), endNodeId, nodeInfoMap, ApiNodeRelations);
            return el;
        } else if (rootNodes.size() > 1) {
            WhenELWrapper when = null;
            for (ApiNode rootNode : rootNodes) {
                ELWrapper el = getEl(rootNode, endNodeId, nodeInfoMap, ApiNodeRelations);
                if (when == null) {
                    when = ELBus.when(el);
                } else {
                    when.when(el);
                }
            }
            return when;
        }
        return null;
    }


    /**
     * 获取多个节点的结束节点
     *
     * @param currentNodes
     * @param nodeInfoMap
     * @param ApiNodeRelations
     * @return
     */
    private static ApiNode getEndNode(List<ApiNode> currentNodes, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> ApiNodeRelations) {
        if (currentNodes.size() > 1) {
            // 获取路径
            List<String> pathList = getEndNode2(currentNodes, nodeInfoMap, ApiNodeRelations);
            // 判断相同的节点
            for (int i = 0; i < pathList.size(); i++) {
                String path = pathList.get(i);
                String[] ids = path.split(",");
                for (String id : ids) {
                    Integer hasCount = hasThisIdNum(id, pathList);
                    if (hasCount == pathList.size()) {
                        return nodeInfoMap.get(id);
                    }
                }
            }
        } else if (currentNodes.size() == 1) {
            ApiNode ApiNode = currentNodes.get(0);
            return ApiNode;
        }
        return null;
    }

    private static Integer hasThisIdNum(String id, List<String> pathList) {
        Integer hasCount = 0;
        for (int i1 = 0; i1 < pathList.size(); i1++) {
            String path = pathList.get(i1);
            if (path.contains(id)) {
                hasCount++;
            }
        }
        return hasCount;
    }

    private static List<String> getEndNode2(List<ApiNode> currentNodes, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> ApiNodeRelations) {
        List<String> pathList = new ArrayList<>();
        for (ApiNode currentNode : currentNodes) {
            StringBuilder path = new StringBuilder(currentNode.getId());
            List<ApiNode> nextNodes = getNextNode(currentNode, nodeInfoMap, ApiNodeRelations);
            if (nextNodes.size() > 0) {
                if (nextNodes.size() == 1) {
                    path.append(",");
                    path.append(nextNodes.get(0).getId());
                }
                List<String> endNode2 = getEndNode2(nextNodes, nodeInfoMap, ApiNodeRelations);
                for (String s : endNode2) {
                    path.append(",");
                    path.append(s);
                }
            }
            pathList.add(path.toString());
        }
        return pathList;
    }

    private static List<ELWrapper> getEls(List<ApiNode> currentNodes, ApiNode endNode, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> ApiNodeRelations) {
        List<ELWrapper> els = new ArrayList<>(currentNodes.size());
        for (ApiNode currentNode : currentNodes) {
            ELWrapper el = getEl(currentNode, endNode != null ? endNode.getId() : null, nodeInfoMap, ApiNodeRelations);
            els.add(el);
        }
        return els;
    }

    private static List<ApiNode> getRootNode(List<ApiNodeRelation> ApiNodeRelations,
                                             List<ApiNode> projectApiNodeList,
                                             Map<String, ApiNode> nodeInfoMap) {
        if (ApiNodeRelations.size() > 0) {
            List<ApiNode> values = new ArrayList<>();
            Map<String, List<ApiNodeRelation>> relationMap = ApiNodeRelations.stream().collect(Collectors.groupingBy(ApiNodeRelation::getTargetNodeId));

            for (ApiNode ApiNode : projectApiNodeList) {
                String uuid = ApiNode.getId();
                if (StringUtils.isBlank(ApiNode.getParentId())) {
                    List<ApiNodeRelation> relationExecDtos = relationMap.get(uuid);
                    if (relationExecDtos == null) {
                        values.add(ApiNode);
                    }
                }
            }
            return values;
        } else {
            List<ApiNode> results = new ArrayList<>();
            for (ApiNode ApiNode : projectApiNodeList) {
                if (StringUtils.isBlank(ApiNode.getParentId())) {
                    results.add(ApiNode);
                }
            }
            return results;
        }
    }


    private static List<ApiNode> getChildrenRootNode(List<ApiNodeRelation> ApiNodeRelations,
                                                     List<ApiNode> projectApiNodeList,
                                                     Map<String, ApiNode> nodeInfoMap) {
        if (ApiNodeRelations.size() > 0) {
            List<ApiNode> values = new ArrayList<>();
            Map<String, List<ApiNodeRelation>> relationMap = ApiNodeRelations.stream().collect(Collectors.groupingBy(ApiNodeRelation::getTargetNodeId));

            for (ApiNode ApiNode : projectApiNodeList) {
                String uuid = ApiNode.getId();
                List<ApiNodeRelation> relationExecDtos = relationMap.get(uuid);
                if (relationExecDtos == null) {
                    values.add(ApiNode);
                }
            }
            return values;
        } else {
            return projectApiNodeList;
        }
    }

    private static List<ApiNode> getRootNode2(ApiNode node, List<ApiNodeRelation> ApiNodeRelations,
                                              Map<String, ApiNode> nodeInfoMap) {
        List<ApiNode> values = new ArrayList<>();
        if (ApiNodeRelations.size() > 0) {
            for (ApiNodeRelation ApiNodeRelation : ApiNodeRelations) {
                if (ApiNodeRelation.getTargetNodeId().equals(node.getId())) {
                    ApiNode ApiNode = nodeInfoMap.get(ApiNodeRelation.getSourceNodeId());
                    if (StringUtils.isBlank(ApiNode.getParentId())) {
                        return getRootNode2(ApiNode, ApiNodeRelations, nodeInfoMap);
                    }
                }
            }
        }
        values.add(node);
        return values;
    }

    private static List<ApiNode> getNextNode(ApiNode currentNode, Map<String, ApiNode> nodeInfoMap, List<ApiNodeRelation> ApiNodeRelations) {
        List<ApiNode> resList = new ArrayList<>();
        for (ApiNodeRelation ApiNodeRelation : ApiNodeRelations) {
            if (ApiNodeRelation.getSourceNodeId().equals(currentNode.getId())) {
                ApiNode ApiNode1 = nodeInfoMap.get(ApiNodeRelation.getTargetNodeId());
                if (ApiNode1 != null && ApiNode1.getType() != NodeCodeEnum.CATCH_END) {
                    resList.add(ApiNode1);
                }
            }
        }
        return resList;
    }
}
